package app.stock.web;

import java.io.IOException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import app.common.Util;
import app.stock.common.Account;
import app.stock.common.Constants;
import app.stock.common.Stock;
import app.stock.common.Summary;
import app.stock.common.Transaction;
import app.stock.server.StockManager;

public class RequestHandler {

    public void handleRequest(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        String page = req.getParameter(WebConstants.key_page);
        if (page == null) {
            String reqURL = req.getRequestURL().toString();
            page = reqURL.substring(reqURL.lastIndexOf("/") + 1);
        }
        String action = req.getParameter(WebConstants.key_action);
        if (action == null) {
            action = "query";
        }
        System.out.println("RequestHandler.handleRequest:page=" + page
                + ",action=" + action);

        StockManager sm = new StockManager();
        if (WebConstants.page_transaction_list.equals(page)) {
            doTxListPage(req, resp, action, sm);
        } else if (WebConstants.page_transaction_add.equals(page)) {
            if ("add".equals(action)) {
                RequestDispatcher rd = req
                        .getRequestDispatcher(WebConstants.page_transaction_list);
                Transaction tx = this.contructTransaction(req);
                tx.account = (Account) req.getSession().getAttribute(
                        WebConstants.sessionAttrName_Account);
                sm.addTransaction(tx);
                rd.forward(req, resp);
            }
        } else if (WebConstants.page_transaction_edit.equals(page)) {
            if ("update".equals(action)) {
                RequestDispatcher rd = req
                        .getRequestDispatcher(WebConstants.page_transaction_list);
                Transaction tx = this.contructTransaction(req);
                sm.updateTransaction(tx);
                rd.forward(req, resp);
            }
        } else if (WebConstants.page_summary.equals(page)) {
            doSummaryPage(req, resp, action, sm);
        } else if (WebConstants.page_login.equals(page)) {
            Account acct = new Account();
            acct.name = req.getParameter(Account.nameName);
            acct.password = req.getParameter(Account.passwordName);
            RequestDispatcher rd = req
                    .getRequestDispatcher(WebConstants.page_stockCtrl
                            + "?page=" + WebConstants.page_transaction_list
                            + "&" + WebConstants.key_action + "=query");
            rd.forward(req, resp);
        } else {
            if ("ajax".equals(action)) {
                String command = req.getParameter("command");
                if ("getStockList".equals(command)) {
                    Stock stCriteria = new Stock();
                    if (Util.hasValue(req.getParameter(Transaction.codeName))) {
                        stCriteria.code = req
                                .getParameter(Transaction.codeName);
                    }
                    List stList = sm.getStockList(stCriteria);
                    resp.getWriter().print(((Stock) stList.get(0)).name);
                }
            }
        }
    }

    protected void doTxListPage(HttpServletRequest req,
            HttpServletResponse resp, String action, StockManager sm)
            throws ServletException, IOException {
        if ("query".equals(action)) {
            RequestDispatcher rd = req
                    .getRequestDispatcher(WebConstants.page_transaction_list);
            Transaction txCondition = new Transaction();
            txCondition.type = req.getParameter(Transaction.typeName);
            txCondition.code = req.getParameter(Transaction.codeName);
            txCondition.account = (Account) req.getSession().getAttribute(
                    WebConstants.sessionAttrName_Account);
            List txList = sm.getTransactionList(txCondition);
            int pageIndex = 1;
            String pageIndexStr = req.getParameter("pageIndex");
            if (Util.hasValue(pageIndexStr)) {
                pageIndex = Integer.parseInt(pageIndexStr);
            }
            List txList2 = new ArrayList();
            for (int i = 0; i < Constants.pageSize; i++) {
                int pos = Constants.pageSize * (pageIndex - 1) + i;
                if (pos < txList.size()) {
                    txList2.add(txList.get(pos));
                }
            }
            req.setAttribute(WebConstants.key_attr_txList, txList2);
            req.setAttribute(WebConstants.key_attr_txNum, txList.size());
            rd.forward(req, resp);
        } else if ("add".equals(action)) {
            RequestDispatcher rd = req
                    .getRequestDispatcher(WebConstants.page_transaction_add);
            rd.forward(req, resp);
        } else if ("update".equals(action)) {
            RequestDispatcher rd = req
                    .getRequestDispatcher(WebConstants.page_transaction_edit);
            rd.forward(req, resp);
        } else if ("delete".equals(req.getParameter(WebConstants.key_action))) {
            RequestDispatcher rd = req
                    .getRequestDispatcher(WebConstants.page_transaction_list);
            Transaction tx = this.contructTransaction(req);
            tx = sm.deleteTransaction(tx);
            rd.forward(req, resp);
        }
    }

    protected void doSummaryPage(HttpServletRequest req,
            HttpServletResponse resp, String action, StockManager sm)
            throws ServletException, IOException {
        if ("query".equals(action)) {
            Transaction txCondition = new Transaction();
            txCondition.account = (Account) req.getSession().getAttribute(
                    WebConstants.sessionAttrName_Account);
            txCondition.code = req.getParameter(Transaction.codeName);
            List txList = sm.getTransactionList(txCondition);
            Summary summary = sm.getSummary(txList);
            if (Util.hasValue(req.getParameter(Transaction.codeName))) {
                req.setAttribute(WebConstants.key_attr_txList, txList);
                req.setAttribute(WebConstants.key_attr_stockList,
                        summary.stockSummaryList);
                RequestDispatcher rd = req
                        .getRequestDispatcher(WebConstants.page_transaction_list);
                rd.forward(req, resp);
            } else {
                req.setAttribute(WebConstants.key_attr_stockList,
                        summary.stockSummaryList);
                req.setAttribute(WebConstants.key_attr_acct, summary.acct);
                RequestDispatcher rd = req
                        .getRequestDispatcher(WebConstants.page_summary);
                rd.forward(req, resp);
            }
        } else if ("update".equals(action)) {
            String submit = req.getParameter("submit");
            System.out.println("submit=" + submit);
            if (submit != null) {
                List stList = sm.getStockSummaryList(null);
                String[] prices = req
                        .getParameterValues(Stock.currentPriceName);
                System.out.println(Arrays.asList(prices));
                for (int i = 0; i < stList.size(); i++) {
                    Stock st = (Stock) stList.get(i);
                    st.currentPrice = Float.parseFloat(prices[i]);
                    sm.updateStockCurrrentPrice(st);
                }
            }
            Transaction txCondition = new Transaction();
            txCondition.account = (Account) req.getSession().getAttribute(
                    WebConstants.sessionAttrName_Account);
            txCondition.code = req.getParameter(Transaction.codeName);
            List txList = sm.getTransactionList(txCondition);
            Summary summary = sm.getSummary(txList);
            if (Util.hasValue(req.getParameter(Transaction.codeName))) {
                req.setAttribute(WebConstants.key_attr_txList, txList);
                req.setAttribute(WebConstants.key_attr_stockList,
                        summary.stockSummaryList);
                RequestDispatcher rd = req
                        .getRequestDispatcher(WebConstants.page_transaction_list);
                rd.forward(req, resp);
            } else {
                req.setAttribute(WebConstants.key_attr_stockList,
                        summary.stockSummaryList);
                req.setAttribute(WebConstants.key_attr_acct, summary.acct);
                RequestDispatcher rd = req
                        .getRequestDispatcher(WebConstants.page_summary);
                rd.forward(req, resp);
            }
        } else if ("sort".equals(action)) {
            String columnName = req.getParameter("columnName");
            Transaction txCondition = new Transaction();
            txCondition.account = (Account) req.getSession().getAttribute(
                    req.getSession().getId());
            txCondition.code = req.getParameter(Transaction.codeName);
            List txList = sm.getTransactionList(txCondition);
            Summary summary = sm.getSummary(txList);
            sm.sortStockSummaryList(summary.stockSummaryList, columnName);
            if (Util.hasValue(req.getParameter(Transaction.codeName))) {
                req.setAttribute(WebConstants.key_attr_txList, txList);
                req.setAttribute(WebConstants.key_attr_stockList,
                        summary.stockSummaryList);
                RequestDispatcher rd = req
                        .getRequestDispatcher(WebConstants.page_transaction_list);
                rd.forward(req, resp);
            } else {
                req.setAttribute(WebConstants.key_attr_stockList,
                        summary.stockSummaryList);
                req.setAttribute(WebConstants.key_attr_acct, summary.acct);
                RequestDispatcher rd = req
                        .getRequestDispatcher(WebConstants.page_summary);
                rd.forward(req, resp);
            }
        }
    }

    private Transaction contructTransaction(HttpServletRequest req) {
        Transaction tx = new Transaction();
        if (Util.hasValue(req.getParameter(Transaction.idName))) {
            tx.id = Integer.parseInt(req.getParameter(Transaction.idName));
        }
        if (Util.hasValue(req.getParameter(Transaction.dateName))) {
            DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            try {
                tx.date = df.parse(req.getParameter(Transaction.dateName));
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
        tx.type = req.getParameter(Transaction.typeName);
        tx.code = req.getParameter(Transaction.codeName);
        tx.name = req.getParameter(Transaction.nameName);
        if (Util.hasValue(req.getParameter(Transaction.priceName))) {
            tx.price = Float
                    .parseFloat(req.getParameter(Transaction.priceName));
        }
        if (Util.hasValue(req.getParameter(Transaction.amountName))) {
            tx.amount = Integer.parseInt(req
                    .getParameter(Transaction.amountName));
        }
        if (Util.hasValue(req.getParameter(Transaction.sum1Name))) {
            tx.sum1 = Float.parseFloat(req.getParameter(Transaction.sum1Name));
        }
        if (Util.hasValue(req.getParameter(Transaction.shouxufeiName))) {
            tx.shouxufei = Float.parseFloat(req
                    .getParameter(Transaction.shouxufeiName));
        }
        if (Util.hasValue(req.getParameter(Transaction.yinhuashuiName))) {
            tx.yinhuashui = Float.parseFloat(req
                    .getParameter(Transaction.yinhuashuiName));
        }
        if (Util.hasValue(req.getParameter(Transaction.guohufeiName))) {
            tx.guohufei = Float.parseFloat(req
                    .getParameter(Transaction.guohufeiName));
        }
        return tx;
    }
}
